package com.ys.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;

public final class DateUtil {

	/**
	 * 添加N天
	 */
	public static Date addDays(Date date, int n) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.DAY_OF_MONTH, n);
		
		return c.getTime();
	}

	/**
	 * 添加N天
	 */
	public static Date addDays(String YYYY_MM_DD, int n) {
		Date date = parseYYYY_MM_dd(YYYY_MM_DD);
		return addDays(date, n);
	}

	/**
	 * 月份加减
	 */
	public static Date addMonth(String YYYY_MM, int n) {
		Date date = parseYYYY_MM(YYYY_MM);
		return addMonth(date, n);
	}


	/*
	 * 月份加减
	 */
	public static Date addMonth(Date date, int monthNum) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.MONTH, monthNum);
		return c.getTime();
	}

	/*
	 * 秒数加减
	 */
	public static Date addSecond(Date date, int n) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.SECOND, n);
		
		return c.getTime();
	}

	public static Date parse(String dateStr, String pattern) {
		try {
			return new SimpleDateFormat(pattern).parse(dateStr);
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}

    /**
     * 将带T类型的字符串时间转成正常时间2
     * @param tDate
     * @return
     */
    public static Date parseTDateToDate(String tDate){
        Date resultDate = null;
        if (tDate == null || tDate.length() == 0){
            return null;
        }
        SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
        try {
            resultDate = inputFormat.parse(tDate);
        }catch (Exception ex){
        }
        return  resultDate;
    }
	
	public static String getWeekday_XINGQI(Date date) {

		String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		// 一周的第几天
		int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
		if (w < 0)
			w = 0;
		return weekDays[w];
	}
	
	/**
	 * 获取星期的序号，星期一为1，星期日为7
	 * @param date
	 * @return
	 */
	public static Integer getWeekdayIndex(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		// 一周的第几天
		int w = cal.get(Calendar.DAY_OF_WEEK);
		if (w == 0)
			w = 7;
		return w;
	}
	
	/**
	 * 转换成星期对应的第几天，星期日为第7天
	 * @param weekday 星期几，如：星期一、星期日
	 * @return
	 */
	public static Integer parseXINGQI(String weekday) {
		if (weekday == null || weekday.length() == 0) {
			return null;
		} else if (weekday.equals("星期一")) {
			return 1;
		} else if (weekday.equals("星期二")) {
			return 2;
		} else if (weekday.equals("星期三")) {
			return 3;
		} else if (weekday.equals("星期四")) {
			return 4;
		} else if (weekday.equals("星期五")) {
			return 5;
		} else if (weekday.equals("星期六")) {
			return 6;
		} else if (weekday.equals("星期日")) {
			return 7;
		} else {
			return null;
		}
	}

	/**
	 * 转换月份
	 * @param YYYY_MM 如：2020-02
	 * @return
	 */
	public static Date parseYYYY_MM(String YYYY_MM) {
		String[] s = YYYY_MM.split("-");
		int year = Integer.parseInt(s[0]);
		int month = Integer.parseInt(s[1]) - 1;
		int date = 1;
		Calendar c = Calendar.getInstance();
		c.set(year, month,date);
		return c.getTime();
	}


	/**
	 * 转换日期
	 * @param YYYY_MM_DD 如：2020-02-01
	 * @return
	 */
	public static Date parseYYYY_MM_dd(String YYYY_MM_DD) {
		String[] s = YYYY_MM_DD.split("-");
		int year = Integer.parseInt(s[0]);
		int month = Integer.parseInt(s[1]) - 1;
		int date = Integer.parseInt(s[2]);
		Calendar c = Calendar.getInstance();
		c.set(year, month, date);
		return c.getTime();
	}
	
	/**
	 * 转换日期
	 * @param YYYY_MM_dd_HH_mm_ss 如：2020-02-01 21:23:59
	 * @return
	 */
	public static Date parseYYYY_MM_dd_HH_mm_ss(String YYYY_MM_dd_HH_mm_ss) {
		int year = Integer.parseInt(YYYY_MM_dd_HH_mm_ss.substring(0, 4));
		int month = Integer.parseInt(YYYY_MM_dd_HH_mm_ss.substring(5, 7)) - 1;
		int date = Integer.parseInt(YYYY_MM_dd_HH_mm_ss.substring(8, 10));
		int hourOfDay = Integer.parseInt(YYYY_MM_dd_HH_mm_ss.substring(11, 13));
		int minute = Integer.parseInt(YYYY_MM_dd_HH_mm_ss.substring(14, 16));
		int second = Integer.parseInt(YYYY_MM_dd_HH_mm_ss.substring(17, 19));
		Calendar c = Calendar.getInstance();
		c.set(year, month, date, hourOfDay, minute, second);
		return c.getTime();
	}
	
	/**
	 * 获取两个时间点之间的随机时间
	 * @param startTime 开始的时间
	 * @param endTime 结束的时间
	 * @return
	 */
	public static Date randomTime(Date startTime, Date endTime) {
		long startLong = startTime.getTime();
		long endLong = endTime.getTime();
		long rtn = startLong + (long)(Math.random() * (endLong - startLong));
		
		//如果返回的是开始时间和结束时间，通过递归调用本函数查找随机值
	    if(rtn == startLong || rtn == endLong){
	        return randomTime(startTime, endTime);
	    }
		return new Date(rtn);
	}
	
	public static String getYYYY(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return "" + c.get(Calendar.YEAR);
	}
	
	private static String getYYYY(Calendar c) {
		return "" + c.get(Calendar.YEAR);
	}
	
	public static String getYYYYMM(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return getYYYY(c) + getMM(c);
	}
	
	public static String getYYYY_MM(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return getYYYY(c) + "-" + getMM(c);
	}
	
	public static String getYYYY_MM_DD(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return getYYYY(c) + "-" + getMM(c) + "-" + getDD(c);
	}
	
	public static String getYYMMDD(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return getYYYY(c).substring(2) + getMM(c) + getDD(c);
	}

	public static String getYYYYMMDD(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return getYYYY(c) + getMM(c) + getDD(c);
	}
	
	public static String getYYYY_MM_DD(int year, int month, int day) {
		return "" + year + "-" + (month < 10 ? "0" + month : month) + "-" + (day < 10 ? "0" + day : day);
	}

	/**
	 * 获取格式：yyyy-MM-dd HH:mm:ss
	 * @param date
	 * @return
	 */
	public static String getYYYY_MM_DD_HH_mm_ss(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int year = c.get(Calendar.YEAR);
		int month = c.get(Calendar.MONTH);
		int day = c.get(Calendar.DAY_OF_MONTH);
		int hour = c.get(Calendar.HOUR_OF_DAY);
		int minute = c.get(Calendar.MINUTE);
		int second = c.get(Calendar.SECOND);
		return "" + year + "-"
				+ (month <= 8 ? "0" + (month + 1) : "" + (month + 1)) + "-"
				+ (day <= 9 ? "0" + day : "" + day) + " "
				+  (hour <= 9 ? "0" + hour : "" + hour) + ":"
				+ (minute <= 9 ? "0" + minute : "" + minute) + ":"
				+ (second <= 9 ? "0" + second : "" + second);
	}

	/**
	 * 获取格式：yyyy-MM-dd HH:mm:ss
	 * @param date
	 * @return
	 */
	public static String getYYYY_MM_DDTHH_mm_ssZ(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int year = c.get(Calendar.YEAR);
		int month = c.get(Calendar.MONTH);
		int day = c.get(Calendar.DAY_OF_MONTH);
		int hour = c.get(Calendar.HOUR_OF_DAY);
		int minute = c.get(Calendar.MINUTE);
		int second = c.get(Calendar.SECOND);
		return "" + year + "-"
				+ (month <= 8 ? "0" + (month + 1) : "" + (month + 1)) + "-"
				+ (day <= 9 ? "0" + day : "" + day) + "T"
				+  (hour <= 9 ? "0" + hour : "" + hour) + ":"
				+ (minute <= 9 ? "0" + minute : "" + minute) + ":"
				+ (second <= 9 ? "0" + second : "" + second) + "Z";
	}

	/**
	 * 获取格式：今天yyyy-MM-dd
	 */
	public static String getToday() {
		Date date = new Date();
		return getYYYY_MM_DD(date);
	}
	
	public static String getMM(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int month = c.get(Calendar.MONTH);
		return month <= 8 ? "0" + (month + 1) : "" + (month + 1);
	}
	
	private static String getMM(Calendar c) {
		int month = c.get(Calendar.MONTH);
		return month <= 8 ? "0" + (month + 1) : "" + (month + 1);
	}
	
	public static String getDD(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int day = c.get(Calendar.DAY_OF_MONTH);
		return day <= 9 ? "0" + day : "" + day;
	}
	
	private static String getDD(Calendar c) {
		int day = c.get(Calendar.DAY_OF_MONTH);
		return day <= 9 ? "0" + day : "" + day;
	}
	
	public static String getHH(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int hour = c.get(Calendar.HOUR_OF_DAY);
		return hour <= 9 ? "0" + hour : "" + hour;
	}
	
	private static String getHH(Calendar c) {
		int hour = c.get(Calendar.HOUR_OF_DAY);
		return hour <= 9 ? "0" + hour : "" + hour;
	}
	
	public static String getHHmmssSSS(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int hour = c.get(Calendar.HOUR_OF_DAY);
		int minute = c.get(Calendar.MINUTE);
		int second = c.get(Calendar.SECOND);
		int msecond = c.get(Calendar.MILLISECOND);
		return (hour <= 9 ? "0" + hour : "" + hour)
				+ (minute <= 9 ? "0" + minute : "" + minute)
				+ (second <= 9 ? "0" + second : "" + second)
				+ (msecond <= 9 ? "00" + msecond : (msecond <= 99 ? "0" + msecond : ("" + msecond)));
	}

	/**
	 * 获取格式：HH:mm:ss
	 * @param date
	 * @return
	 */
	public static String getHH_mm_ss(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int hour = c.get(Calendar.HOUR_OF_DAY);
		int minute = c.get(Calendar.MINUTE);
		int second = c.get(Calendar.SECOND);
		return "" +  (hour <= 9 ? "0" + hour : "" + hour) + ":"
				+ (minute <= 9 ? "0" + minute : "" + minute) + ":"
				+ (second <= 9 ? "0" + second : "" + second);
	}
	
	public static String getmm(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int minute = c.get(Calendar.MINUTE);
		return minute <= 9 ? "0" + minute : "" + minute;
	}
	
	public static String getss(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int second = c.get(Calendar.SECOND);
		return second <= 9 ? "0" + second : "" + second;
	}
	
	public static String getSSS(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int msecond = c.get(Calendar.MILLISECOND);
		return msecond <= 9 ? "00" + msecond : (msecond <= 99 ? "0" + msecond : ("" + msecond));
	}

	/**
	 * 获取一个月最后一天
	 * @param yyyy_MM 传入年月参数：yyyy-MM
	 * @return
	 */
	public static Integer getMonthLastDay(String yyyy_MM){
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR,Integer.parseInt(yyyy_MM.split("-")[0]));
		//获取月份，0表示1月份
		cal.set(Calendar.MONTH,Integer.parseInt(yyyy_MM.split("-")[1]) - 1);
		cal.set(Calendar.DAY_OF_MONTH,1);
		int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
		return lastDay;
	}

	/**
	 * 获取两个日期相差多少个月
	 * @param startDate 开始时间 yyyy-MM
	 * @param endDate 结束时间 yyyy-MM
	 * @return
	 * @throws ParseException
	 */
	public static int getMonthSpace(String startDate, String endDate)
			throws ParseException {

		int result = 0;

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");

		Calendar c1 = Calendar.getInstance();
		Calendar c2 = Calendar.getInstance();

		c1.setTime(sdf.parse(startDate));
		c2.setTime(sdf.parse(endDate));

		int i = c2.get(Calendar.YEAR)-c1.get(Calendar.YEAR);
		int month = 0;
		if (i<0)
		{
			month = -i*12;
		}else if(i>0)
		{
			month =  i*12;
		}
		result = (c2.get(Calendar.MONDAY) - c1.get(Calendar.MONTH)) + month;

		return result == 0 ? 1 : Math.abs(result);

	}


	/**
	 * 获取两个时间相差多少分钟
	 * @param startTime 开始时间
	 * @param endTime 结束时间
	 * @return
	 * @throws ParseException
	 */
	public static long getMinutesSpace(Date startTime, Date endTime)
			throws ParseException {

		long diffInMillies = Math.abs(endTime.getTime() - startTime.getTime());
		long diffInMinutes = TimeUnit.MINUTES.convert(diffInMillies, TimeUnit.MILLISECONDS);
		return diffInMinutes;

	}


	/**
	 * 根据年、月获取该月所有的日期(年-月-日)信息
	 */
	public static List<String> getMonthDates(int year, int month) {
		List<String> dates = new ArrayList<>();
		LocalDate startDate = LocalDate.of(year, month, 1);
		LocalDate endDate = startDate.withDayOfMonth(startDate.lengthOfMonth());

		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
		while (!startDate.isAfter(endDate)) {
			dates.add(startDate.format(formatter));
			startDate = startDate.plusDays(1);
		}
		return dates;
	}
	
	/**
	 * 两个日期之间的天数，如2020-02-02和2020-02-01，返回1
	 * @param dateEnd
	 * @param dateBegin
	 * @return
	 */
	public static Integer subtractDate(String dateEnd, String dateBegin) {
		if (dateEnd == null || dateEnd.length() != 10 || dateBegin == null || dateBegin.length() != 10) {
			return null;
		}
		long timeEnd = parseYYYY_MM_dd(dateEnd).getTime();
		long timeBegin = parseYYYY_MM_dd(dateBegin).getTime();
		return Integer.parseInt("" + (timeEnd - timeBegin) / (1000L * 60 * 60 * 24));
	}

	/**
	 * 比较两个日期之间的大小
	 * @param date1 格式：yyyy-MM-dd
	 * @param date2 格式：yyyy-MM-dd
	 * @return <0 日期1早于日期2 ; > 0 日期1晚于日期2 ; = 0 日期1等于日期2
	 */
	public static int compareToDates(String date1, String date2){
		// 将日期字符串转换为LocalDate对象
		LocalDate localDate1 = LocalDate.parse(date1, DateTimeFormatter.ISO_LOCAL_DATE);
		LocalDate localDate2 = LocalDate.parse(date2, DateTimeFormatter.ISO_LOCAL_DATE);

		// 使用compareTo方法比较两个日期对象
		int comparison = localDate1.compareTo(localDate2);
		return comparison;
		/*
		if (comparison < 0) {
			System.out.println("日期1早于日期2");
		} else if (comparison > 0) {
			System.out.println("日期1晚于日期2");
		} else {
			System.out.println("日期1等于日期2");
		}
		 */
	}


	//获取过去30天的日期集合
	public static List<String> getAgoThirtyDay() {
		List<String> dateList = new ArrayList();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Calendar calendar = null;
		for(int i=30;i>0;i--){
			calendar=Calendar.getInstance();
			calendar.add(Calendar.DAY_OF_MONTH, -i);
			String agoDay = sdf.format(calendar.getTime());
			dateList.add(agoDay);
		}
		return dateList;
	}


	/**
	 * 获取最近agoNum个月的月份集合
	 */
	public static List<String> getAgoMonth(int agoNum) {
		List<String> res = new ArrayList();
		Date date = new Date();
		for(int i=agoNum;i>=0;i--){
			String month = getYYYY_MM(addMonth(date, 0-i));
			res.add(month);
		}
		return res;
	}

}
